package com.mikelouis.test.scala.proginscala.chapter28

/**
 * This version of equals and hashCode are symmetric
 * tansitive, but they are too strict.
 * Created by yuazhu on 2/26/2015.
 */
object Points7 {

  // A technically valid, but unsatisfying, equals method
  class Point(val x: Int, val y: Int) {
    override def hashCode = 41 * (41 + x) + y

    override def equals(other: Any) = other match {
      case that: Point =>
        this.x == that.x && this.y == that.y &&
          this.getClass == that.getClass
      case _ => false
    }
  }

  object Color extends Enumeration {
    val Red, Orange, Yellow, Green, Blue, Indigo, Violet = Value
  }

  class ColoredPoint(x: Int, y: Int, val color: Color.Value)
    extends Point(x, y) {

    override def equals(other: Any) = other match {
      case that: ColoredPoint =>
        (this.color == that.color) && super.equals(that)
      case _ => false
    }
  }

  def main(args: Array[String]) {
    val p = new Point(1, 2)
    val redp = new ColoredPoint(1, 2, Color.Red)
    val bluep = new ColoredPoint(1, 2, Color.Blue)
    println(redp == p)
    println(p == bluep)
    println(redp == bluep)

    // too strict
    // pAnon should be equal to p but p and pAnon is two different class => object different
    // p: Point, pAnon:anonymous class of Point
    val pAnon = new Point(1, 1) { override val y = 2 }
    println(p == pAnon)
  }

}
